#include "Broadcast.h"
#include "config.h"

Broadcast::Broadcast(int port) : port_(port), running_(true)
{
    // 创建套接字
    sockfd_ = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd_ < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // 设置套接字选项以允许广播
    int broadcast = 1;
    if (setsockopt(sockfd_, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0) {
        perror("setsockopt");
        close(sockfd_);
        exit(EXIT_FAILURE);
    }

    // 绑定套接字到端口
    sockaddr_in addr;
    std::memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(port_);

    if (bind(sockfd_, (sockaddr*)&addr, sizeof(addr)) < 0) {
        perror("bind");
        close(sockfd_);
        exit(EXIT_FAILURE);
    }

    if (MessageQueueList.find(SOCKETMASSAGE) != MessageQueueList.end()) {
        Msg = MessageQueueList.at(SOCKETMASSAGE);
    } else {
        std::cout<<"Msg不存在";
    }

    // 启动接收线程
    recv_thread_ = std::thread(&Broadcast::receive, this);

}

Broadcast::~Broadcast() 
{
    running_ = false;
    if (recv_thread_.joinable()) {
        recv_thread_.join();
    }
    close(sockfd_);
}

void Broadcast::send(const std::string& message, const std::string& address) {
    sockaddr_in dest_addr;
    std::memset(&dest_addr, 0, sizeof(dest_addr));
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(port_);
    //dest_addr.sin_port = htons(12345);
    if (inet_pton(AF_INET, address.c_str(), &dest_addr.sin_addr) <= 0) {
        perror("inet_pton");
        return;
    }

    if (sendto(sockfd_, message.c_str(), message.size(), 0, (sockaddr*)&dest_addr, sizeof(dest_addr)) < 0) {
        perror("sendto");
    }
}

void Broadcast::receive()
{
    char buffer[1024];
    sockaddr_in sender_addr;
    socklen_t sender_len = sizeof(sender_addr);

    while (running_) {
        ssize_t recv_len = recvfrom(sockfd_, buffer, sizeof(buffer) - 1, 0, (sockaddr*)&sender_addr, &sender_len);
        if (recv_len < 0) {
            perror("recvfrom");
            continue;
        }

        buffer[recv_len] = '\0'; // Null-terminate the received data
        //std::cout << "Received message: " << buffer << std::endl;

        Msg->sendMessage(std::string(buffer));
    }
}